package com.hengpeng.itfin.port;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.hengpeng.common.constant.Constant;
import com.hengpeng.common.persist.QueryParameter;
import com.hengpeng.common.persist.QueryResult;
import com.hengpeng.common.persist.entity.AbstractEntity;
import com.hengpeng.common.persist.query.DynamicQuery;
import com.hengpeng.common.persist.query.SearchResult;
import com.hengpeng.common.persist.query.SqlResult;
import com.hengpeng.common.util.AnnotationScanHelper;
import com.hengpeng.common.util.ObjectHelper;
import com.hengpeng.itfin.domain.TransMethod;
import com.hengpeng.itfin.domain.annotation.RemoteService;
import com.hengpeng.itfin.domain.annotation.RemoteTransaction;
import com.hengpeng.itfin.port.vo.TestVo;
import com.hengpeng.itfin.service.ServiceFactory;
import com.hengpeng.itfinbase.message.ResponseMessage;
import com.hengpeng.itfinbase.message.TransMessage;

/**
 * <pre>
 * 远程服务接口实现
 * </pre>
 * @author linriqing
 * @version 1.0, 2012-3-8
 */
@Controller("remoteService")
@RequestMapping(value = "/RemoteService")
public class RemoteServiceFacade implements ApplicationContextAware
{
	private final static Log logger = LogFactory.getLog(RemoteServiceFacade.class);

	private static final Map<Integer, TransMethod> transMethods = new HashMap<Integer, TransMethod>();

	@Autowired
	private ServiceFactory servicefactory;

	@RequestMapping(value = "/remoteQuery", method = RequestMethod.POST)
	@ResponseBody
	public <T extends AbstractEntity> QueryResult<T> remoteQuery(@RequestBody QueryParameter<T> queryParameters)
	{
		QueryResult<T> queryResult = new QueryResult<T>();
		DynamicQuery customQuery = queryParameters.getCustomQuery();
		try
		{
			// 限制客户端提交的查询记录页大小,未设pagesize的默认最大为10000
			SqlResult sqlResult = customQuery.getSqlResult();
			Integer pageSize = sqlResult.getPageSize();
			if (pageSize == null || pageSize < 1)
			{
				pageSize = 10000;
				customQuery.setPageSize(pageSize);
			}
			SearchResult<T> result = servicefactory.getPersistService().findByDynamicQueryPage(
					queryParameters.getType(), customQuery);
			queryResult.setResults(result.getResult());
			if (result.getCount() != null)
			{
				queryResult.setTotalCount(result.getCount());
			}
			if (customQuery.getPageIndex() != null)
			{
				queryResult.setPageIndex(customQuery.getPageIndex());
			}
			if (customQuery.getPageSize() != null)
			{
				queryResult.setPageSize(customQuery.getPageSize());
			}
			if (queryResult.getResults().size() > 10000)
			{
				logger.error("异常查询, Query{" + customQuery.getSqlResult().getSql() + "}, Parameter{"
						+ customQuery.getSqlResult().getParamsList() + "}");
				queryResult.getResults().clear();
			}
			queryResult.setIsSuccess(true);
		}
		catch (Exception e)
		{
			logger.error("异常查询, Query{" + customQuery.getSqlResult().getSql() + "}, Parameter{"
					+ customQuery.getSqlResult().getParamsList() + "}处理异常", e);
			queryResult.setIsSuccess(false);
		}
		return queryResult;
	}

	@RequestMapping(value = "/remoteTrans", method = RequestMethod.POST)
	@ResponseBody
	public TransMessage remoteTrans(@RequestBody TransMessage transMessage)
	{
		TransMethod transMethod = transMethods.get(transMessage.getTransType());
		try
		{
			Object managedBean = transMethod.getManagedBean();
			Method method = transMethod.getMethod();
			TransMessage invoke = (TransMessage) method.invoke(managedBean, transMessage);
			invoke.setClientId(transMessage.getClientId());
			invoke.setId(transMessage.getId());
			invoke.setTransType(transMessage.getTransType());
			return invoke;
		}
		catch (Exception e)
		{
			e.printStackTrace();
			logger.error("调用服务程序异常..." + ObjectHelper.toJson(transMessage), e);
			ResponseMessage response = new ResponseMessage();
			response.setClientId(transMessage.getClientId());
			response.setId(transMessage.getId());
			response.setTransType(transMessage.getTransType());
			response.setRespCode(Constant.TRANSACTION_RESPONSE_CODE_UNKOWN);
			response.setRespDesc("调用服务程序异常...");
			return response;
		}
	}

	@RequestMapping(value = "/test")
	@ResponseBody
	public TestVo test()
	{
		TestVo vo = new TestVo();
		vo.setId(1001l);
		vo.setName("rabbit测试");
		return vo;
	}

	@RequestMapping(value = "/test1")
	@ResponseBody
	public TestVo test1(@RequestBody TestVo tvo)
	{
		System.out.println("TestVo name = " + tvo.getName());
		TestVo vo = new TestVo();
		vo.setId(1002l);
		vo.setName("rabbit1测试");
		return vo;
	}

	@Override
	public void setApplicationContext(ApplicationContext context) throws BeansException
	{
		if (transMethods.size() == 0)
		{
			List<Class<?>> findAnnotationByType = AnnotationScanHelper.findAnnotationByType(RemoteService.class);
			for (Class<?> clazz : findAnnotationByType)
			{
				Service annotation = clazz.getAnnotation(Service.class);
				logger.info("加载服务模块：" + clazz.getName());
				String beanName = annotation.value();
				if (beanName.isEmpty())
				{
					String simpleName = clazz.getSimpleName();
					beanName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1);
				}
				Object bean = context.getBean(beanName);
				Method[] declaredMethods = clazz.getDeclaredMethods();
				for (Method method : declaredMethods)
				{
					RemoteTransaction annotation2 = method.getAnnotation(RemoteTransaction.class);
					if (annotation2 != null)
					{
						int transType = annotation2.transType();
						logger.info("注册交易服务接口：" + transType + " - "
								+ (annotation2.value().isEmpty() ? method.getName() : annotation2.value()));
						transMethods.put(transType, new TransMethod(bean, method));
					}
				}
			}
		}
	}
}
